﻿using RenderHeads.Media.AVProVideo;
using System;
using UnityEngine;
using UnityEngine.UI;

namespace BToolkit.ExeUtils
{
    public class VideoController : MonoBehaviour
    {
        public MediaPlayer target;
        public BButton btnPause, btnPlay;
        public BSlider progress;
        public Text txtTime;
        public BSlider volume;

        public RectTransform rectTransform { get { return transform as RectTransform; } }
        private bool isPlayingWhenStartDrag;

        private void Awake()
        {
            AVProPlayer player = GetComponent<AVProPlayer>();
            player.onLoaded.AddListener(() =>
            {
                Vector2 size = rectTransform.sizeDelta;
                size.y = player.rawImage.texture.height;
                rectTransform.sizeDelta = size;
            });

            btnPause.canTriggerInterval = 0;
            btnPlay.canTriggerInterval = 0;
            btnPause.gameObject.SetActive(false);
            btnPlay.gameObject.SetActive(true);

            btnPause.AddClick(() =>
            {
                if (target && target.Control != null && target.Control.IsPlaying())
                {
                    target.Pause();
                    btnPause.gameObject.SetActive(false);
                    btnPlay.gameObject.SetActive(true);
                }
            });

            btnPlay.AddClick(() =>
            {
                if (target && target.Control != null && !target.Control.IsPlaying())
                {
                    target.Play();
                    btnPause.gameObject.SetActive(true);
                    btnPlay.gameObject.SetActive(false);
                }
            });

            progress.onStartDrag = () =>
            {
                if (target && target.Control != null)
                {
                    isPlayingWhenStartDrag = target.Control.IsPlaying();
                    target.Control.Pause();
                }
            };

            progress.onStopDrag = () =>
            {
                if (target && target.Control != null && target.Info != null)
                {
                    target.Control.Seek(target.Info.GetDurationMs() * progress.value);
                    if (isPlayingWhenStartDrag)
                    {
                        target.Control.Play();
                    }
                }
            };

            txtTime.text = "00:00/00:00";

            volume.onChangeValue += (float v) =>
            {
                if (target && target.Control != null)
                {
                    target.Control.SetVolume(v);
                    PlayerPrefs.SetFloat("Volume", v);
                }
            };

            target.Events.AddListener(OnMediaPlayerEvent);
        }

        private void OnEnable()
        {
            volume.value = PlayerPrefs.GetFloat("Volume", 0.5f);
        }

        private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
        {
            switch (et)
            {
                case MediaPlayerEvent.EventType.ReadyToPlay:
                    break;
                case MediaPlayerEvent.EventType.Started:
                    btnPause.gameObject.SetActive(true);
                    btnPlay.gameObject.SetActive(false);
                    break;
                case MediaPlayerEvent.EventType.FirstFrameReady:
                    break;
                case MediaPlayerEvent.EventType.MetaDataReady:
                case MediaPlayerEvent.EventType.ResolutionChanged:
                    break;
                case MediaPlayerEvent.EventType.FinishedPlaying:
                    btnPause.gameObject.SetActive(false);
                    btnPlay.gameObject.SetActive(true);
                    break;
            }
        }

        private void Update()
        {
            if (target && target.Info != null && target.Info.GetDurationMs() > 0f)
            {
                float time = target.Control.GetCurrentTimeMs();
                float duration = target.Info.GetDurationMs();
                progress.value = Mathf.Clamp(time / duration, 0.0f, 1.0f);

                DateTime currDT = new DateTime((long)time * 10000);
                DateTime durationDT = new DateTime((long)duration * 10000);
                txtTime.text = currDT.ToString("mm:ss") + "/" + durationDT.ToString("mm:ss");
            }
        }
    }
}